﻿using System;
using System.Collections.Generic;
using System.Collections;
using IBatisNet.Common.Exceptions;
using IBatisNet.DataAccess.Interfaces;
using IBatisNet.DataMapper;
using IBatisNet.DataAccess;
namespace AUV5.DAL
{
    /// <summary>
    /// Summary description for BaseSqlMapDao.
    /// </summary>
    public class BaseSqlMapDao : IDao
    {
        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        private static IBatisNet.DataMapper.ISqlMapper mapper = null;

        private readonly object objsync = new object();

        public ISqlMapper Mapper
        {
            get
            {
                if (mapper == null)
                {
                    lock (objsync)
                    {
                        if (mapper == null)
                        {
                            mapper = GetLocalSqlMap();
                        }
                    }
                }
                return mapper;
            }
        }

        public BaseSqlMapDao()
        {
            mapper = GetLocalSqlMap();
        }

        /// <summary>
        /// Looks up the parent DaoManager, gets the local transaction
        /// (which should be a SqlMapDaoTransaction) and returns the
        /// SqlMap associated with this DAO.
        /// </summary>
        /// <returns>The SqlMap instance for this DAO.</returns>
        protected ISqlMapper GetLocalSqlMap()
        {
            //IDaoManager daoManager = DaoManager.GetInstance(this);
            //SqlMapDaoSession sqlMapDaoSession = (SqlMapDaoSession)daoManager.LocalDaoSession;
            //return sqlMapDaoSession.SqlMap;
            return IBatisNet.DataMapper.Mapper.Instance();
        }

        /// <summary>
        /// get list
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="stateMentName"></param>
        /// <param name="parameterObject"></param>
        /// <returns></returns>
        protected IList<T> ExecuteQueryForList<T>(string statementName, object parameterObject)
        {
            try
            {
                return mapper.QueryForList<T>(statementName, parameterObject);
            }
            catch (Exception e)
            {
                throw new IBatisNetException("Error executing query '" + statementName + "' for list.  Cause: " + e.Message, e); 
            }
        }

        /// <summary>
        /// get key value list
        /// </summary>
        /// <param name="statementName"></param>
        /// <param name="parameterObject"></param>
        /// <param name="keyProperty"></param>
        /// <returns></returns>
        public IDictionary<T, V> ExecuteQueryForIDictionary<T, V>(string statementName, object parameterObject, string keyProperty)
        {
            try
            {
                return (IDictionary<T, V>)mapper.QueryForDictionary<T, V>(statementName, parameterObject, keyProperty);
            }
            catch (Exception e)
            {
                throw new IBatisNetException("Error executing query '" + statementName + "' for list.  Cause: " + e.Message, e); ;
            }
        }

        /// <summary>
        /// Simple convenience method to wrap the SqlMap method of the same name.
        /// Wraps the exception with a IBatisNetException to isolate the SqlMap framework.
        /// </summary>
        /// <param name="statementName"></param>
        /// <param name="parameterObject"></param>
        /// <returns></returns>
        protected IList ExecuteQueryForList(string statementName, object parameterObject)
        {
            try
            {
                //getsql(statementName, parameterObject);
                return mapper.QueryForList(statementName, parameterObject);
            }
            catch (Exception e)
            {
                throw new IBatisNetException("Error executing query '" + statementName + "' for list.  Cause: " + e.Message, e);
            }
        }

        /// <summary>
        /// Simple convenience method to wrap the SqlMap method of the same name.
        /// Wraps the exception with a IBatisNetException to isolate the SqlMap framework.
        /// </summary>
        /// <param name="statementName"></param>
        /// <param name="parameterObject"></param>
        /// <param name="skipResults"></param>
        /// <param name="maxResults"></param>
        /// <returns></returns>
        protected IList ExecuteQueryForList(string statementName, object parameterObject, int skipResults, int maxResults)
        {
            try
            {
                return mapper.QueryForList(statementName, parameterObject, skipResults, maxResults);
            }
            catch (Exception e)
            {
                throw new IBatisNetException("Error executing query '" + statementName + "' for list.  Cause: " + e.Message, e);
            }
        }

        /// <summary>
        /// get details
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        protected object ExecuteQueryForObject<T>(string statementName, object parameterObjec)
        {
            try
            {
                return mapper.QueryForObject<T>(statementName, parameterObjec);
            }
            catch (Exception e)
            {
                throw new IBatisNetException("Error executing query '" + statementName + "' for object.  Cause: " + e.Message, e);
            }
        }

        /// <summary>
        /// Simple convenience method to wrap the SqlMap method of the same name.
        /// Wraps the exception with a IBatisNetException to isolate the SqlMap framework.
        /// </summary>
        /// <param name="statementName"></param>
        /// <param name="parameterObject"></param>
        /// <returns></returns>
        protected object ExecuteQueryForObject(string statementName, object parameterObject)
        {
            try
            {
                return mapper.QueryForObject(statementName, parameterObject);
            }
            catch (Exception e)
            {
                throw new IBatisNetException("Error executing query '" + statementName + "' for object.  Cause: " + e.Message, e);
            }
        }

        /// <summary>
        /// Simple convenience method to wrap the SqlMap method of the same name.
        /// Wraps the exception with a IBatisNetException to isolate the SqlMap framework.
        /// </summary>
        /// <param name="statementName"></param>
        /// <param name="parameterObject"></param>
        /// <returns></returns>
        protected int ExecuteUpdate(string statementName, object parameterObject)
        {
            try
            {
                return mapper.Update(statementName, parameterObject);
            }
            catch (Exception e)
            {
                throw new IBatisNetException("Error executing query '" + statementName + "' for update.  Cause: " + e.Message, e);
            }
        }

        /// <summary>
        /// Simple convenience method to wrap the SqlMap method of the same name.
        /// Wraps the exception with a IBatisNetException to isolate the SqlMap framework.
        /// </summary>
        /// <param name="statementName"></param>
        /// <param name="parameterObject"></param>
        /// <returns></returns>
        protected object ExecuteInsert(string statementName, object parameterObject)
        {
            try
            {
                return mapper.Insert(statementName, parameterObject);
            }
            catch (Exception e)
            {

                throw new IBatisNetException("Error executing query '" + statementName + "' for insert.  Cause: " + e.Message, e);
            }
        }

        /// <summary>
        /// delete
        /// </summary>
        /// <param name="id"></param>
        protected int ExecuteDelete(string statementName, object parameterObjec)
        {
            try
            {
                return mapper.Delete(statementName, parameterObjec);
            }
            catch (Exception e)
            {
                throw new IBatisNetException("Error executing query '" + statementName + "' for delete.  Cause: " + e.Message, e);
            }
        }

        #region  在执行查询的同时生成Json数据
        /// <summary>
        /// Execute For Json
        /// </summary>
        /// <param name="statementName"></param>
        /// <param name="parameterObject"></param>
        /// <param name="handler"></param>
        /// <returns></returns>
        protected void ExecuteWithRowDelegate(string statementName, object parameterObject, RowDelegate handler)
        {
            try
            {
                //mapper.QueryForList(statementName, parameterObject);
                mapper.QueryWithRowDelegate(statementName, parameterObject, handler);
            }
            catch (Exception e)
            {
                throw new IBatisNetException("Error executing query '" + statementName + "' for JSon.  Cause: " + e.Message, e);
            }

        }
        #endregion


        protected string GetSqlString(string statementname, object paramobject)
        {
            IBatisNet.DataMapper.MappedStatements.IMappedStatement statement = mapper.GetMappedStatement(statementname);

            if (!mapper.IsSessionStarted)
            {
                mapper.OpenConnection();
            }

            IBatisNet.DataMapper.Scope.RequestScope scope = statement.Statement.Sql.GetRequestScope(statement, paramobject, mapper.LocalSession);

            return scope.PreparedStatement.PreparedSql;

            ////by amos
            //mapper.CloseConnection();

            //return string.Empty;
        }
    }
}
